#pragma once

#include "znx_event_loop.h"
#include "comm/znx_hooks.h"

typedef struct {
    int                         nthreads;
    znx_event_loop_data_t       *datas;
    znx_thread_base_t           *threads;
    znx_hooks_t                 *init_hook_chain;
    znx_hooks_t                 *proc_exit_chain;
    znx_hooks_t                 *quit_hook_chain;
} znx_worker_processor_t;


void znx_worker_processor_init();


// hook_add must be called before znx_worker_processor_start.
// hook_handler(loop_data)
void znx_worker_processor_add_init_hook(znx_hook_handler_pt hook_handler);


// hook_add must be called before znx_worker_processor_start.
// hook_handler(loop_data)
void znx_worker_processor_add_proc_exit_hook(znx_hook_handler_pt hook_handler);


// hook_add must be called before znx_worker_processor_start.
// hook_handler(loop_data)
void znx_worker_processor_add_quit_hook(znx_hook_handler_pt hook_handler);


// run in main thread.
void znx_worker_processor_start(
    int nthreads,
    int64_t mem_freelist_level,
    int64_t aligned_mem_freelists_level);


void znx_worker_processor_stop();


void znx_worker_processor_post_event(znx_dispatch_event_t *dispatch_event);

znx_bool_t znx_worker_processor_all_task_done();

extern char *znx_worker_thread_tag;

static inline znx_bool_t
current_thread_is_worker_thread()
{
    if (current_thread_base == NULL) {
        return ZNX_FALSE;
    }

    if (current_thread_base->tag != znx_worker_thread_tag) {
        return ZNX_FALSE;
    }

    return ZNX_TRUE;
}

